home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 40
/
Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso
/
Aminet
/
misc
/
emu
/
ATUtilities.lha
/
ATUtilities
/
ASM
/
RAMDRIVE.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-09-26
|
29KB
|
722 lines
Page ,132
title RDISK.ASM - Virtuelles Laufwerk
;**********************************************************;
; RDISK.ASM RAM-Disk fr Expanded Memory / Hauptspeicher. ;
; Version: 1.1 ;
; Sprache: Microsoft MASM 4.0 oder hher ;
; Autor: M. Greve ;
;bersetzen: MASM /ML RDISK; ;
; LINK RDISK; ;
; EXE2BIN RDISK.EXE RDISK.SYS ;
; Anwendung: DEVICE=RDISK.SYS [xxx] [/A] ;
;**********************************************************;
;-----( Befehle des EMM-Interrupts 67h )--------------------
EMM = 67h ;Interrupt
EMMframe = 41h ;Segment-Adr. des EMM
EMMfree = 42h ;Freie Seiten ermitteln
EMMalloc = 43h ;EMM-Seiten zuteilen
EMMmapp = 44h ;Seite ins Fenster laden
EMMsave = 47h ;EMM-Zustand sichern
EMMreset = 48h ;EMM-Zugriff zulassen
;-----( Status-Codes )--------------------------------------
CMD_ERR = 8103h ;Ungltiger Befehl
CRC_ERR = 8104h ;CRC-Fehler
SEC_ERR = 8108h ;Ungltiger Sektor
GEN_ERR = 810Ch ;Undefinierter Fehler
SZ_ERR = 00000001b ;Ungengend Speicher
NoEMM_ERR = 00000100b ;Kein Expanded Speicher
EMM_ERR = 00001000b ;Exp. Speicher Fehler
OPT_ERR = 00010000b ;Ungltige Option
;-----( Allg. Konstanten )----------------------------------
MEDIA_ID = 0F8h ;Media Descriptor Byte
MAXFAT = 0FF7h ;Max. Anzahl FAT-Eintrge
EXPANDED = 1 ;Expanded Speicher-Flag
MIN_MEM = 64 ;Min. freier Speicher
MIN_REQ = 16 ;kleinstmgliche RamDisk
SECSZ = 512 ;Byte / Sektor
DFLTSZ = 128 ;Default Diskgráe (64kB)
MAXCMD = 12 ;Max. zugelassener Befehl
READCMD = 4 ;Nummer des Lesebefehls
CR = 0Dh
LF = 0Ah
BEEP = 7
;-----( Request-Header-Strukturen )-------------------------
RH equ ES:[DI] ;Zugriffszeiger fr Request-Header
RHx STRUC ;Gemeinsame Felder im Reqest-Header
db ? ;Lnge d. Req.-Header
db ? ;Gerte-(Einheit)-Nummer
CMDcode db ? ;Befehls-Code
CMDstat dw ? ;Statuswort
dq ? ;Reserviert fr DOS
RHx ENDS
RH0 STRUC ;Fn.0:Init; Fn.1:Media Check; Fn.2: Build-BPB
db (TYPE RHx) DUP (?) ; gemeinsamer Teil
Unum db ? ;Anzahl inst. Gerte
EndOfs dw ? ;Ende des Treibers, Offs
EndSeg dw ? ;Ende des Treibers, Segm
BPBofs dw ? ;BPB Tabelle, Offset
BPBseg dw ? ;BPB Tabelle, Segment
DrvCode db ? ;Laufw.-Code ab DOS 3.xx
RH0 ENDS
MediaCh equ byte ptr EndOfs ;"Media Change" Flag
BPBadr equ dword ptr BPBofs;32Bit Adresse des BPB
;Beim Aufruf von "Init" zeigt BPBofs auf "DEVICE=" Zeile.
ConfigLn equ dword ptr BPBofs
RH4 STRUC ;Fn.4:Read; Fn.8:Write; Fn.9:Write/Verify
db (TYPE RHx) DUP (?) ;gemeinsamer Teil
db ? ;Media Descriptor Byte
DTAadr dd ? ;DTA adresse (32Bit)
SecCnt dw ? ;Sektorenzhler
StrtSec dw ? ;Erster Sektor
RH4 ENDS
;-----( Text-Ausgabe-Makro )--------------------------------
@Print MACRO Text
push DX
lea DX,Text
mov AH,9
int 21h
pop DX
ENDM
;-----( Programmbeginn )------------------------------------
CODE SEGMENT para public
ASSUME CS:CODE, DS:CODE
ORG 0
Main:
;-----( Gertetreiberkopf )---------------------------------
DvcHdr dd -1 ;Zeiger auf nchsten Treiber
dw 0800h ;Block-Treiber-Attribut
dw Strategy ;Strategy Routine
dw DVCintrpt ;Interrupt-Routine
db 'RAMD 1.0' ;Treibername (8Byte)
ReqHdr dd ? ;Request-Header-Adresse
;-----( Funktionstabelle )----------------------------------
; Alle Funktionen werden ber die Adresse ES:Dispatch[BX]
; aufgerufen und kehren mit dem Fehlercode im AX-Register
; zu DOS zurck.
;-----------------------------------------------------------
Dispatch dw Init ; 0 - Initialisierung
dw MedChk ; 1 - Diskettenwechsel
dw BldBPB ; 2 - BPB aufbauen
dw Exit ; 3 - I/O Ctrl Ein
dw Read ; 4 - Block lesen
dw Exit ; 5 - Zeichen lesen
dw Exit ; 6 - Eing. Status
dw Exit ; 7 - Eingabe lschen
dw Write ; 8 - Block schreiben
dw Write ; 9 - Schreiben mit Verify
dw Exit ;10 - Ausgabe Status
dw Exit ;11 - Ausgabe lschen
dw Exit ;12 - I/O Control Aus
;-----( Datenbereich )--------------------------------------
Progname db CR,LF,'RDISK.SYS - (c) 1990 '
db 'c''t / M. H. Grev',CR,LF,'$'
EVEN ;gerade Adresse fr Stack!
db 32 dup ('stak') ;programminterner Stack
Stak: ;Stack-Kopf
oldSP dw ? ;alter Stack-Pointer
oldSS dw ?
oldAX dw ? ;Ablage fr AX-Register
Cmd db ? ;aktueller Befehl
MemTyp db 0 ;0 = Hauptspeicher
;1 = Expanded Speicher
Npages dw DFLTSZ/16 ;Diskgráe in EMM-Seiten
FrameSeg dw ? ;Segment des EMM-Fensters
XfrSec dw ? ;Sektor
XfrCnt dw ? ;Sektorenzhler
XfrAdr label dword ;lokale Kopie der
XfrAdrO dw ? ;DTA-Adresse
XfrAdrS dw ?
EMMhdl dw ? ;EMM-Handle
LastPge dw -1 ;Zuletzt verw. EMM-Seite
;-----( BIOS-Parameter-Block )------------------------------
BPB equ $
SecSz dw SECSZ ;Byte/Sektor
ClstrSz db 2 ;Sektoren/Cluster
ResSecs dw 1 ;Reserv. Sektoren
db 1 ;Anzahl FAT-Kopien
NDir dw DFLTSZ/4 ;Eintr. im Root
DiskSz dw DFLTSZ ;Anzahl Sektoren
db MEDIA_ID ;Media descriptor
FATsec dw 2 ;Sektoren pro FAT
dw 8 ;Sektoren pro Spur
dw 1 ;Lesekpfe
dw 0 ;Versteckte Sektoren
BPBlen equ $ - BPB ;Lnge des BPB
BPBptr dw offset BPB ;Zeiger auf BPB
;-----( Strategy )------------------------------------------
; Sichert Zeiger auf Request-Header
;-----------------------------------------------------------
Strategy proc far
mov word ptr CS:ReqHdr,BX
mov word ptr CS:ReqHdr+2,ES
ret
Strategy endp
;-----( Gertetreiber-"Interrupt" )-------------------------
DVCintrpt proc far
mov CS:oldAX,AX ;Wert von AX sichern
mov CS:oldSP,SP ;Alten Stack-Pointer sichern
mov CS:oldSS,SS
mov AX,CS
cli
mov SS,AX ;Eigenen Stack einrichten
mov SP,offset Stak
sti
push BX
push CX
push DX
push DS
push ES
push DI
push SI
push BP
mov DS,AX ;DS-> Unsere Daten
les DI,ReqHdr ;ES:DI -> Request-Header
mov BL,RH.CMDcode ;BX = Befehls-Code
sub BH,BH
cmp BL,MAXCMD ;Befehl gltig ?
mov AX,CMD_ERR ;Fehler-Code
ja DVCend ;Abbruch!
or BX,BX ;Initialisierung ?
jz DVC1 ;Ja
test MemTyp,EXPANDED ;EMM-Speicher ?
jz DVC1 ;Nein
mov AH,EMMsave ;EMM-Speicherzustand sichern
mov DX,EMMhdl
int EMM
or AH,AH
jnz DVCerr
DVC1: add BX,BX ;BX = Befehlsindex
call Dispatch[BX] ;Aufruf des Befehls
les DI,ReqHdr ;ES:DI->Req. Header
test MemTyp,EXPANDED
jz DVCend
cmp RH.CMDcode,0 ;Init. Befehl?
je DVCend ;Ja
push AX ;Statuswort sichern
mov AH,EMMreset ;EMM-Zugriff zulassen
mov DX,EMMhdl
int EMM
or AH,AH ;EMM-Fehler ?
pop AX
jz DVCend ;Alles OK
DVCerr: mov AX,GEN_ERR ;Fehler melden
DVCend: mov RH.CMDstat,AX ;Status in Req. Hdr ablegen
pop BP ;Register zurcksetzen
pop SI
pop DI
pop ES
pop DS
pop DX
pop CX
pop BX
cli
mov SS,CS:oldSS
mov SP,CS:oldSP ;den Stack nicht vergessen !
sti
mov AX,CS:oldAX
ret
DVCintrpt endp
;-----( Funktion 1: Media Check )---------------------------
; Ueberprft ob Diskette gewechselt wurde.
;-----------------------------------------------------------
MedChk: mov RH.MediaCh,1 ; nicht gewechselt
sub AX,AX ; (es ist ja eine RAM-Disk!)
ret
;-----( Funktion 2: Build BPB )-----------------------------
; Adresse der BPB-Tabelle an DOS zurckgeben.
;-----------------------------------------------------------
BldBPB: mov RH.BPBofs,offset BPB
mov RH.BPBseg,CS
sub AX,AX
ret
;-----( Funktionen 4, 8 und 9: Disk-Ein/Ausgabe )-----------
Read:
Write: cld ;Richtungsflag lschen
mov LastPge,-1 ;Letzte EMM-Seite
mov AL,RH.CMDcode
mov Cmd,AL ;Befehl sichern
mov AX,RH.StrtSec ;Erster Sektor > Diskgráe?
cmp AX,DiskSz
ja RWerr1 ;Ja, Sektorfehler
mov XfrSec,AX ;Ersten Sektor sichern
mov BX,RH.SecCnt ;Anzahl Sektoren sichern
add AX,BX ;letzter Sektor > Diskgráe?
cmp AX,DiskSz
ja RWerr1 ;Ja, Sektorfehler
mov XfrCnt,BX ;Anzahl Sektoren sichern
les DI,RH.DTAadr ;Zeiger fr DTA-Adresse
mov XfrAdrO,DI ;sichern
mov XfrAdrS,ES
RW0: cmp XfrCnt,0 ;alle Sektoren kopiert ?
jz RWEnd ;Ja, Ende
mov AX,XfrSec
call MapSec ;ES:DI ->Sektor
or AH,AH
jnz RWerr2
lds SI,XfrAdr ;DS:SI ->DOS Buffer(DTA)
cmp CS:Cmd,READCMD
jnz RW1
xchg SI,DI ;Fr Lese-Befehl,
push ES ;Adressen vertauschen
push DS
pop ES
pop DS
RW1: mov CX,SECSZ/2 ;Anzahl Worte
rep movsw
mov AX,CS ;DS ->unsere Daten
mov DS,AX
dec XfrCnt ;Zhler - 1
inc XfrSec
add XfrAdrO,SECSZ
jmp RW0 ;nchsten Sektor
RWerr1: mov AX,SEC_ERR ;Expanded-Memory-Fehler
jmp RWEnd
RWerr2: mov AX,CRC_ERR ;Ungltiger Sektor
RWEnd: ret
;-----( Ungenutzte Funktionen )-----------------------------
Exit: mov AX,CMD_ERR
ret
;-----( Sektornummer in Speicheradresse umwandeln )---------
; Eingabe: AX = Sektornummer
; Ausgabe: ES:DI = -> Sektor
; AH <> 0: Fehler
;-----------------------------------------------------------
MapSec: test MemTyp,EXPANDED
jz MapSec2
push AX ;EMM-Speicher
mov CX,5 ;2^5=32 Sektoren/EMM-Seite
shr AX,CL ;AX =EMM-Seite
cmp AX,LastPge ;bereits eingeblendet ?
je MapSec1 ;Ja
mov LastPge,AX ;Nein, Seitennummer sichern
mov BX,AX ;logische Seite 'BX' in
sub AL,AL ;physikalische Seite 0
mov AH,EMMmapp ;einblenden
mov DX,EMMhdl
int EMM
or AH,AH
jnz MapSecE
MapSec1:pop DI ;DI = Sektornummer
and DI,01Fh ;Maske f. unterste 5 Bit
mov CX,9
shl DI,CL ;ES:DI -> Segment Adresse
mov ES,FrameSeg
jmp MapSecE
MapSec2:mov CX,5 ;2^5=32 Paragraphen
shl AX,CL ;pro 512 Byte Sektor
add AX,FrameSeg ;Segment-Adresse
mov ES,AX ;CX = Segment
sub DI,DI ;BX = 0 = Offset
sub AX,AX
MapSecE:ret
;-----( Ende des Treibers )---------------------------------
; Wenn die RAM-Disk im Hauptspeicher installiert wird, ist
; dies gleichzeitig der Anfang des Boot-Sektors (Sektor 0
; der RAM-Disk). Der nachfolgende Code befindet sich inner-
; halb dieses Sektors. Der Assemblerzeiger wird dazu auf
; eine runde Paragraphenadresse gesetzt. Beim Einsatz von
; Expanded Memory, ist dies das Ende des Treibers.
;-----------------------------------------------------------
DVCLEN = ($-Main+15)/16 ;Treiberlnge in Paragraphen
ORG DVCLEN*16
BootRec db 0,0,0 ;Sektor 0 der Disk
db 'RDISK1.0' ;8 Byte Bezeichnung
BootBPB db BPBlen dup (?) ;Reservierter fr den BPB
BOOTlen equ $ - offset BootRec
;----- (Funktion 0: Treiber installieren )------------------
ErrFlag db 0 ;Flag fr Fehlermeldungen
Init: call Parse ;Kommandozeile auswerten
call Parms ;BPB Parameter berechnen
call SetUp ;Speicher reservieren
call Format ;Disk formatieren
call SignOn ;Meldungen ausgeben
call FillRH ;Parameter Rckgabe an DOS
test ErrFlag,-1 ;Installationsfehler?
jnz InitEnd
;FAT/Root Sektoren aus temp.
mov AX,ResSecs ;Bereich an ihren end-
call MapSec ;gltigen Platz verschieben.
mov AX,32
mul NDir ;Anz. Bytes im Root-Verz.
mov CX,AX
mov AX,512
mul FATsec ;Anz. Bytes im FAT-Bereich
add CX,AX
push DS ;DS hinberretten
mov DX,CS ;Prog.Segment + Prog.lnge
add DX,DRIVERend ; = Adresse des
mov DS,DX ;temporren Speichers
sub SI,SI ;DS:SI -> temp. FAT/Root
rep movsb ;Daten kopieren
pop DS
InitEnd:ret
;-----( "DEVICE="-Zeile auswerten )------------------------
; Eingabe: ES:DI = -> Request-Header
; Ausgabe: DX = Diskgráe in KByte
;-----------------------------------------------------------
Parse: les DI,RH.ConfigLn ;ES:DI -> Text
sub DX,DX
ParsNxt:mov AL,ES:[DI]
sub AH,AH
inc DI ;DI -> nchstes Zeichen
cmp AL,CR ;Zeilenende?
je Parse1
cmp AL,'/' ;Optionszeichen ?
je Option1
cmp AL,'-' ;altern. Optionszeichen ?
je Option1
mov CX,AX
sub CL,'0' ;numerisch ?
jb ParsNxt ;Nein
cmp CL,9
ja ParsNxt ;Nein
mov AX,10
mul DX ;bisheriger Wert * 10
add AX,CX ;neuen Wert hinzuzhlen
mov DX,AX
jmp ParsNxt
Option1:mov AL,ES:[DI]
inc DI
mov BH,AL
cmp BH,'A' ;Expanded Memory ?
jne Option2 ;Nein, weiter
mov MemTyp,EXPANDED ;Speicherflag setzen
jmp ParsNxt
Option2:cmp BH,'D' ;DOS-Speicher
je ParsNxt ;keine weitere Optionen
or ErrFlag,OPT_ERR
jmp short Parse2
Parse1: cmp DX,MIN_REQ ;Mindestgráe einstellen
ja Parse2
mov DX,MIN_REQ
Parse2: test MemTyp,EXPANDED
jz Parse3
and DX,NOT 15 ;Auf volle 16kB abrunden
mov Npages,DX
mov CX,4
shr Npages,CL
Parse3: ret
;-----( BPB-Daten berechnen )-------------------------------
; BPB-Daten berechnen und in den Bootrecord schreiben.
; Pro 4 KB Diskkapazitt wird ein Root-Verzeichnis-Eintrag
; zugelassen (bis max 512). Wir verwenden eine 12-Bit-FAT.
; Dadurch ist die maximale Anzahl Clusters 0FF7hex(4087).
; Eingabe: DX = Diskgráe in KByte
; Ausgabe: AX,BX,CX,DX zerstrt
;-----------------------------------------------------------
Parms: mov DiskSz,DX
shl DiskSz,1 ;Anzahl Sektoren
shr DX,1 ;Anzahl Verzeichnisse
shr DX,1
cmp DX,512 ;< 512 ?
jb SetDir ;Ja
mov DX,512
SetDir: mov NDir,DX ;Anzahl Verzeichnisse
mov AX,DiskSz
mov CX,2 ;default= 2 Sektoren/Cluster
SetClr: shr AX,1 ;Anzahl Cluster auf Disk
cmp AX,MAXFAT ;zuviele Clusters ?
jb ClrOk ;Nein
shl CX,1 ;Sekt/Cluster verdoppeln
jmp SetClr
ClrOk: mov ClstrSz,CL ;Anzahl Clusters pro FAT
mov BX,AX ;AX = Anzahl Clusters
add AX,BX ;AX = 2 * Clusters
add AX,BX ;AX = 3 * Clusters
;= doppelte FAT Lnge
add AX,1023 ;aufrunden
mov CX,10 ; FAT-Lnge
shr AX,CL ;FATsec = -------------
mov FATsec,AX ; Byte / Sektor
ret
;-----( Speicher reservieren, RDisk-Adresse berechnen )-----
; Eingabe: keine
; Ausgabe: ES = Segmentadresse der "Disk"
;-----------------------------------------------------------
SetUp: test MemTyp,EXPANDED ;Expanded Memory?
jz DMEMsu ;Nein
EMMsu: mov AH,35h ;EMM vorhanden ?
mov AL,EMM ;Adresse des Int 67h
int 21h ;bestimmen
mov DI,0Ah ;ID-String des EMM
mov SI,offset EMMname
mov CX,8
cld
repz cmpsb ;String vergleichen
jz EMMsu1
or ErrFlag,NoEMM_ERR
jmp short SUexit
EMMsu1: mov AH,EMMframe ;Segment des EMM-Speichers lesen
int EMM
mov FrameSeg,BX
or AH,AH
jz EMMsu2
or ErrFlag,EMM_ERR
jmp short SUexit
EMMsu2: mov AH,EMMfree ;Freien Speicher bestimmen
int EMM
or AH,AH
jz EMMsu3
or ErrFlag,EMM_ERR
jmp short SUexit
EMMsu3: or BX,BX ;Speicher belegt ?
jnz EMMsu4 ;Nein
or ErrFlag,SZ_ERR
EMMsu4: cmp Npages,BX ;Genug Speicher ?
jbe EMMsu5
or ErrFlag,SZ_ERR
jmp short SUexit
EMMsu5: mov AH,EMMalloc ;Speicher im EMM reservieren
mov BX,Npages ;BX = Anzahl Seiten
int EMM
mov EMMhdl,DX ;Handle sichern
or AH,AH
jz SUexit
or ErrFlag,SZ_ERR
jmp SUexit
DMEMsu: mov AX,CS ;Speicher berechnen
add AX,DVCLEN ;Ende des Treibers ist zugl.
mov FrameSeg,AX ;Anfang der RAM-Disk
sub DX,DX ;Division vorbereiten
mov BX,64 ;Paragraphen/KB
div BX
add DX,-1 ;auf volle KB aufrunden
adc AX,MIN_MEM ;+ minimaler freier Speicher
mov DX,DiskSz ;= Diskgráe in Sektoren
shr DX,1 ;/2 = Diskgráe in KB
add AX,DX ;Erforderlicher Speicher
push AX ;Wert sichern
int 12h ;Speichergráe bestimmen
pop DX
sub AX,DX ;groá genug ?
jnc SUexit ;Ja
or ErrFlag,SZ_ERR ;Nein, Fehler
SUexit: mov ES,FrameSeg
ret
;-----( RAM-Disk "Formatieren" )---------------------------
Format: test MemTyp,EXPANDED ;Expanded Memory?
jnz FrmtEXP ;Ja
mov DX,CS
add DX,DRIVERend
mov ES,DX
mov BX,DiskSz ;Anzahl Sektoren
xor AX,AX
Format1:mov CX,SECSZ/2 ;Worte/Sektor
xor DI,DI
rep stosw
add DX,SECSZ/16
mov ES,DX ;ES ->nchsten Sektor
dec BX
jnz Format1
jmp Format5
FrmtEXP:mov ES,FrameSeg ;EMM-Fenster Segment
mov BX,Npages ;Anzahl EMM-Seiten
Format2:dec BX ;Seite anwhlen und
mov AH,EMMmapp ;einblenden
xor AL,AL
mov DX,EMMhdl
int EMM
or AH,AH ;Fehler ?
jnz FrmtErr ;Ja!
mov CX,2000h ;Anzahl Worte/EMMseite
xor DI,DI
rep stosw
or BX,BX
jnz Format2
Format5:push DS ;Bootrecord aufbauen
pop ES ;ES = Datensegment
mov DI,offset BootBPB
mov SI,offset BPB
mov CX,BPBlen
rep movsb
sub AX,AX ;Bootrecord kopieren
call MapSec ;ES:DI -> Sektor 0
mov SI,offset BootRec
mov CX,BOOTlen
rep movsb
mov DX,CS ;FAT und Verzeichnis
add DX,DRIVERend ; vorbergehend am Ende
mov ES,DX ; des Programms aufbauen.
sub DI,DI ;ES:DI-> auf FAT
mov AL,MEDIA_ID
stosb ;Media Descriptor Byte
mov AX,-1 ;...und zwei FFh Byte
stosw
mov AX,512
mul FATsec
sub AX,3 ; 3 Byte weniger...
mov CX,AX ; = Zhler
sub AX,AX ;Rest der FAT lschen
rep stosb ;DI zeigt jetzt auf Root
mov SI,offset VolLabel
mov CX,VolLen ;"Volume Name" ins
rep movsb ;Verzeichnis kopieren
mov AX,32
mul NDir
sub AX,VolLen
mov CX,AX ;CX = Anzahl Bytes im Verz.
xor AX,AX ;Rest des Verzeichnisses
rep stosb ;lschen
jmp short FrmtEnd
FrmtErr:or ErrFlag,EMM_ERR ;Fehler melden!
FrmtEnd:ret
;------( Daten im Request-Header sichern )------------------
FillRH: mov AX,CS ;Gráe des Treibers
add AX,DVCLEN
test MemTyp,EXPANDED
jnz FillRH1
mov DX,DiskSz ;Disk ist im Hauptspeicher.
mov CX,5 ;Diskgráe in Sektoren
shl DX,CL ;* 2^5 Paragr./Sektor
add AX,DX
FillRH1:les DI,ReqHdr ;Fehler bei Installation ?
test ErrFlag,-1
jnz FillRH2
mov RH.Unum,1 ;Anzahl der Gerte
mov RH.EndOfs,0 ;Programmendeadresse
mov RH.EndSeg,AX
mov RH.BPBofs, offset BPBptr
mov RH.BPBseg,CS ;Adresse des BPB-Zeigers.
sub AX,AX
ret
FillRH2:mov RH.Unum,0 ;kein Gert, kein Speicher!
mov RH.EndOfs,0
mov RH.EndSeg,CS
mov AX,GEN_ERR
ret
;------( Installation melden )------------------------------
SignOn: @Print Progname
test ErrFlag,SZ_ERR ;Installationsfehler melden
jz SignOn1
@Print ErrMess3
SignOnE:@Print ErrMess0
ret
SignOn1:test ErrFlag,NoEMM_ERR
jz SignOn2
@Print ErrMess1
jmp SignOnE
SignOn2:test ErrFlag,EMM_ERR
jz SignOn3
@Print ErrMess2
jmp SignOnE
SignOn3:test ErrFlag,OPT_ERR
jz SignOn4
@Print ErrMess4
jmp SignOnE
SignOn4:mov AH,30h ;DOS-Version ?
int 21h
cmp AL,3 ; 3.xx ?
jb SignOn5
les DI,ReqHdr
mov AL,RH.DrvCode ;Diskbezeichnung holen
add AL,'A'
mov Drive,AL
SignOn5:mov CL,4 ;Reservierte Sektoren:
mov AX,NDir
shr AX,CL ; Root-Verzeichnis
add AX,FATsec ; + FAT
add AX,2
and AX,0FFFEh ;auf gerade Zahl aufrunden
mov DX,DiskSz ;Diskgráe - Res. Sektoren
sub DX,AX ; = Freie Sektoren
mov AX,SECSZ ;* (Byte/Sektor)
mul DX ; = Diskgráe in Byte
mov SI,offset DiskSize+7
call BinAsci ;in ASCII umwandeln
mov AX,NDir ;Anzahl Verzeichnisse
cwd ;oberes Wort lschen
mov SI,offset DirNum+7
call BinAsci
mov AX,DiskSz ;bentigter Speicher
mov DX,SECSZ
mul DX
mov SI,offset MemSize+7
call BinAsci
@Print Mess1 ;Meldungen ausgeben
@Print Mess2
mov DX,offset DOSmem
test MemTyp,EXPANDED
jz SignOn6
mov DX,offset EXPmem
SignOn6:mov AH,9
int 21h
@Print Mess3
ret
;-----( BIN-Zahl in ASCII String umwandeln )----------------
; Eingabe: DX:AX = 32-Bit-Zahl
; DS:SI = -> Ende des String Puffers
; Ausgabe: DS:SI = -> Anfang des String Puffers
;-----------------------------------------------------------
BinAsci:xor BP,BP
xchg BP,DX ;BP = oberes Wort
mov CX,10 ;CX = Teiler
BAloop: xchg AX,BP ;oberes Wort holen
xor DX,DX ;Ergebnis lschen
div CX
xchg AX,BP ;unteres Wort holen
div CX
or DL,'0' ;in ASCII-Zahl umwandeln
mov [SI],DL ;and drop at target
dec SI ;set up for next character
or AX,AX ;noch was zu tun?
jnz BAloop ;Ja, weiter
ret
;-----( Transienter Datenbereich )--------------------------
EMMname db 'EMMXXXX0' ;Bezeichnung des EMM-Handlers
VolLabel db 'RDISK V:1.0' ;"Volume" Name: 11 Bytes
db 28h ;Volume Attribut
dt 0 ;10 reservierte Bytes
dw 24576 ;12:00 Uhr
dw 4865 ;1.August.1989
db 6 dup (0) ;6 reservierte Bytes
VolLen = $ - VolLabel ;Lnge
Mess1 db 'RAM-Disk '
Drive db '$: $'
Mess2 db 'erfolgreich installiert.',CR,LF
DiskSize db ' Bytes verfgbar.',CR,LF
DirNum db ' Verzeichnisse im ¯Root®.',CR,LF
MemSize db ' Bytes $'
DOSmem db 'DOS-Speicher $'
EXPmem db 'Expanded Memory $'
Mess3 db 'wurden verwendet.',CR,LF,'$'
ErrMess1 db 'Kein Expanded Memory vorhanden',CR,LF,'$'
ErrMess2 db 'Fehler im EMM-Treiber',CR,LF,'$'
ErrMess3 db 'Zu wenig Speicher frei',CR,LF,'$'
ErrMess4 db 'Unbekannte Option',CR,LF,'$'
ErrMess0 db 'RAM-Disk NICHT installiert.',CR,LF,BEEP,'$'
;-----( Programmende )--------------------------------------
DRIVERend = ($-Main+15)/16 ;Prog.Lnge in Paragraphen
CODE ends
END Main